/*******************************************************************************
 * Copyright (c) 2008-2009 zhang yuexiang.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */ 
package org.xfeep.asura.bootstrap;

import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlList;
import javax.xml.bind.annotation.XmlType;

import org.xfeep.asura.core.ComponentDefinition;
import org.xfeep.asura.core.ComponentType;
import org.xfeep.asura.core.ContractType;
import org.xfeep.asura.core.CoreConsts;
import org.xfeep.asura.core.ReferenceDefinition;
import org.xfeep.asura.core.config.ConfigService;
import org.xfeep.asura.core.match.Matcher;
import org.xfeep.asura.core.match.SmartMatcher;
import org.xfeep.asura.core.reflect.TypeItem;

@XmlType
public class ConfigReferenceDefinintionInfo {

	@XmlAttribute
	public String _cid="";
	@XmlAttribute
	public boolean required = true;
	@XmlAttribute
	public ContractType contractType = ContractType.CAREFUL;
	@XmlList
	@XmlElement
	public List<String> configProperties = new ArrayList<String>();
	
	public static ConfigReferenceDefinintionInfo convert(ReferenceDefinition crd) {
		if (! CoreConsts.CONFIG_SERVICE_REF_NAME.equals(crd.getName()) ){
			throw new IllegalArgumentException("must be ReferenceDefinitionInfo with name=" + CoreConsts.CONFIG_SERVICE_REF_NAME);
		}
		ConfigReferenceDefinintionInfo crdi = new ConfigReferenceDefinintionInfo();
		crdi._cid = (String)crd.getMatcher().getOndemandConfigRequirement().get(CoreConsts.CONFIG_ID);
		crdi.contractType = crd.getContractType();
		crdi.required = crd.getMultiplicityType().isRequired();
		if (crd.getInjectProperties() != null){
			for (TypeItem t :  crd.getInjectProperties()){
				crdi.configProperties.add(t.getName());
			}
		}
		return crdi;
	}
	
	public List<ReferenceDefinition> createConfigReferenceDefinintion(ComponentDefinition cd) {
		
		List<ReferenceDefinition> rt = new ArrayList<ReferenceDefinition>();
//		TypeItem[] bindItems = new TypeItem[configProperties.size()];
//		for (int i = 0; i < configProperties.size(); i++){
//			bindItems[i] = itemMap.get(configProperties.get(i));
//		}
		if (_cid.length() != 0 && !CoreConsts.VAR_SOURCE_CONFIG_ID.equals(_cid)){
			ReferenceDefinition configReferenceDefinintion = 
				new ReferenceDefinition(cd, CoreConsts.CONFIG_SERVICE_REF_NAME, ConfigService.class, SmartMatcher.getMatcher(CoreConsts.CONFIG_ID+"="+_cid + Matcher.ON_DEMAND_SEPRATOR), null);
			configReferenceDefinintion.setOrder(CoreConsts.CONFIG_REF_DEFALUT_ORDER);
//			configReferenceDefinintion.setInjectProperties(bindItems);
			rt.add(configReferenceDefinintion);
		}
		if (cd.getType() == ComponentType.FACTORY || cd.getType() == ComponentType.ON_DEMAND){
			ReferenceDefinition configReferenceDefinintion = 
				new ReferenceDefinition(cd, CoreConsts.CONFIG_SERVICE_REF_NAME, ConfigService.class, SmartMatcher.getMatcher(CoreConsts.CONFIG_ID+"="+CoreConsts.VAR_SOURCE_CONFIG_ID+ Matcher.ON_DEMAND_SEPRATOR), null);
//			configReferenceDefinintion.setInjectProperties(bindItems);
			configReferenceDefinintion.setOrder(CoreConsts.CONFIG_REF_DEFALUT_ORDER);
			rt.add(configReferenceDefinintion);
		}
		return rt;
		
	}
	
}
